{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Adagrad with `Gluon`\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:48:52.102890Z",
     "start_time": "2017-10-22T11:48:51.384380Z"
    }
   },
   "outputs": [],
   "source": [
    "import mxnet as mx\n",
    "from mxnet import autograd\n",
    "from mxnet import gluon\n",
    "from mxnet import ndarray as nd\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "mx.random.seed(1)\n",
    "random.seed(1)\n",
    "\n",
    "# Generate data.\n",
    "num_inputs = 2\n",
    "num_examples = 1000\n",
    "true_w = [2, -3.4]\n",
    "true_b = 4.2\n",
    "X = nd.random_normal(scale=1, shape=(num_examples, num_inputs))\n",
    "y = true_w[0] * X[:, 0] + true_w[1] * X[:, 1] + true_b\n",
    "y += .01 * nd.random_normal(scale=1, shape=y.shape)\n",
    "dataset = gluon.data.ArrayDataset(X, y)\n",
    "\n",
    "net = gluon.nn.Sequential()\n",
    "net.add(gluon.nn.Dense(1))\n",
    "square_loss = gluon.loss.L2Loss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:48:52.374911Z",
     "start_time": "2017-10-22T11:48:52.104689Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib as mpl\n",
    "mpl.rcParams['figure.dpi']= 120\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def train(batch_size, lr, epochs, period):\n",
    "    assert period >= batch_size and period % batch_size == 0\n",
    "    net.collect_params().initialize(mx.init.Normal(sigma=1), force_reinit=True)\n",
    "    # Adagrad.\n",
    "    trainer = gluon.Trainer(net.collect_params(), 'adagrad',\n",
    "                            {'learning_rate': lr})\n",
    "    data_iter = gluon.data.DataLoader(dataset, batch_size, shuffle=True)\n",
    "    total_loss = [np.mean(square_loss(net(X), y).asnumpy())]\n",
    "    \n",
    "    for epoch in range(1, epochs + 1):\n",
    "        for batch_i, (data, label) in enumerate(data_iter):\n",
    "            with autograd.record():\n",
    "                output = net(data)\n",
    "                loss = square_loss(output, label)\n",
    "            loss.backward()\n",
    "            trainer.step(batch_size)\n",
    "\n",
    "            if batch_i * batch_size % period == 0:\n",
    "                total_loss.append(np.mean(square_loss(net(X), y).asnumpy()))\n",
    "        print(\"Batch size %d, Learning rate %f, Epoch %d, loss %.4e\" % \n",
    "              (batch_size, trainer.learning_rate, epoch, total_loss[-1]))\n",
    "\n",
    "    print('w:', np.reshape(net[0].weight.data().asnumpy(), (1, -1)), \n",
    "          'b:', net[0].bias.data().asnumpy()[0], '\\n')\n",
    "    x_axis = np.linspace(0, epochs, len(total_loss), endpoint=True)\n",
    "    plt.semilogy(x_axis, total_loss)\n",
    "    plt.xlabel('epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:48:54.014985Z",
     "start_time": "2017-10-22T11:48:52.377643Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch size 10, Learning rate 0.900000, Epoch 1, loss 5.3231e-05\n",
      "Batch size 10, Learning rate 0.900000, Epoch 2, loss 4.9388e-05\n",
      "Batch size 10, Learning rate 0.900000, Epoch 3, loss 4.9256e-05\n",
      "w: [[ 1.99946415 -3.39996123]] b: 4.19967 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nRaUkSZI6+z8EgSNAzTCPKgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1119d5d30>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "train(batch_size=10, lr=0.9, epochs=3, period=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next\n",
    "[RMSProp from scratch](../chapter06_optimization/rmsprop-scratch.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For whinges or inquiries, [open an issue on  GitHub.](https://github.com/zackchase/mxnet-the-straight-dope)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
